﻿using System;
using System.Linq;
using System.Threading;
using System.Collections.Generic;

namespace SimbaRGVMonitor.Controllers
{
    partial class MonitorTcpDataBuffer
    {
        public MonitorTcpDataBuffer()
            : this(TimeSpan.FromMinutes(5))
        {

        }

        public MonitorTcpDataBuffer(TimeSpan timeout)
        {
            Timeout = timeout;
            cleanThread = new Thread(LoopClean) { IsBackground = true };

            InitializeSettings();
        }

        //====================================================================================================
        //以上是类型构造函数
        //----------------------------------------------------------------------------------------------------
        //以下是类型字段
        //====================================================================================================

        private readonly Thread cleanThread;
        private readonly object syncThreadLock = new object();
        private readonly List<ReceiveData> bufferList = new List<ReceiveData>();

        //====================================================================================================
        //以上是类型字段
        //----------------------------------------------------------------------------------------------------
        //以下是类型属性
        //====================================================================================================

        public TimeSpan Timeout { get; set; }
        public int Count { get { return bufferList.Count; } }

        //====================================================================================================
        //以上是类型属性
        //----------------------------------------------------------------------------------------------------
        //以下是初始化设置
        //====================================================================================================

        public void InitializeSettings()
        {
            cleanThread.Start();
        }

        //====================================================================================================
        //以上是初始化设置
        //----------------------------------------------------------------------------------------------------
        //以下是压入缓存数据
        //====================================================================================================

        public void PushData(object data)
        {
            var receiveData = new ReceiveData(data);
            lock (syncThreadLock)
            {
                bufferList.Add(receiveData);
            }
        }

        //====================================================================================================
        //以上是压入缓存数据
        //----------------------------------------------------------------------------------------------------
        //以下是获取缓存数据
        //====================================================================================================

        public bool TryTakeData(Predicate<object> predicate, out object data)
        {
            lock (syncThreadLock)
            {
                var receiveData = bufferList.FirstOrDefault(item => predicate(item.Data));
                var success = receiveData != null;
                if(success)
                {
                    bufferList.Remove(receiveData);
                }

                data = success == false ? null : receiveData.Data;
                return success;
            }
        }

        //====================================================================================================
        //以上是获取缓存数据
        //----------------------------------------------------------------------------------------------------
        //以下是清空缓存数据
        //====================================================================================================

        public void CleadData()
        {
            lock (syncThreadLock)
            {
                bufferList.Clear();
            }
        }

        //====================================================================================================
        //以上是清空缓存数据
        //----------------------------------------------------------------------------------------------------
        //以下是清理缓存数据
        //====================================================================================================

        private void LoopClean()
        {
            while (true)
            {
                var removeDatas = CollectTimeoutDatas();
                foreach (var data in removeDatas)
                {
                    lock (syncThreadLock)
                    {
                        bufferList.Remove(data);
                    }
                }

                Thread.Sleep(1000);
            }
        }

        private ReceiveData[] CollectTimeoutDatas()
        {
            lock (syncThreadLock)
            {
                return CollectTimeoutDatasCore().ToArray();
            }
        }

        private IEnumerable<ReceiveData> CollectTimeoutDatasCore()
        {
            foreach (var data in bufferList)
            {
                var timespan = DateTime.Now - data.ReceiveTime;
                if (timespan > Timeout)
                {
                    yield return data;
                }
            }
        }
    }
}
